package pri.abner.practice.stream;

import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 *@description 静态数据源（包括各种Stream的方法应用）
 *@author abner chow
 *@date 2019-06-03 17:07
 */
public class Data {

    private static List<Person> list = new ArrayList();

    static {
        Person wu = Person.builder().idNumber(1).name("吴良").age(19).sex("man").build();
        Person zhang = Person.builder().idNumber(23).name("张美丽").age(23).sex("woman").build();
        Person liu = Person.builder().idNumber(32).name("刘丹").age(13).sex("man").build();
        Person hua = Person.builder().idNumber(14).name("华谷").age(52).sex("woman").build();
        Person zou = Person.builder().idNumber(12).name("邹春花").age(52).sex("woman").build();
        Person qian = Person.builder().idNumber(6).name("好大夫").age(20).sex("man").build();
        Person li = Person.builder().idNumber(7).name("吴良").age(17).sex("man").build();
        list = Arrays.asList(wu, zhang, liu, hua, zou, qian, li);
    }

    /**
     * @param
     * @return java.util.List
     * @description 获取数据
     * @author abner chow
     * @date 2019/6/3 17:14
     */
    public static List getData() {
        return list;
    }


    /**
     * @description 过滤
     * @param
     * @return java.util.List<pri.abner.practice.stream.Person>
     * @author abner chow
     * @date 2019/6/3 17:56
     */
    public static List<Person> sexFilter() {

        List<Person> data = Data.getData();
        System.out.println("-------------------------- stream 过滤器 filter ---------------------------------------");
        data.forEach((person -> {
            System.out.println(person.getName() + " " + person.getSex() + " " + person.getAge());
        }));
        System.out.println("-------------------------- 过滤性别是man ---------------------------------------");
        List<Person> filterResult = data.stream().filter(e -> e.getSex().equals("man")).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(filterResult)) {
            filterResult.forEach((Person person) -> {
                System.out.println(person.getName() + " " + person.getSex());
            });
        }
        return filterResult ;

    }


    /**
     * @description 获取所有用户的名称列表
     * @param
     * @return java.util.List<java.lang.String>
     * @author abner chow
     * @date 2019/6/3 18:00
     */
    public static List<String> getUserNameList() {
        List<Person> personList = Data.getData();
        System.out.println("-------------------------- stream map 用法 ---------------------------------------");

        //获取所有的用户名
        List<String> nameList = personList.stream().map(person -> person.getName()).collect(Collectors.toList());

        //第二种方式
        List<String> nameList2 = personList.stream().map(Person::getName).collect(Collectors.toList());

        System.out.println("过滤所有的用户名并返回");
        //第三种方式
        List<String> nameList3 = personList.stream().map(person -> {
            System.out.println(person.getName());
            return person.getName();}).collect(Collectors.toList());
        return  nameList;

    }


    /**
     * @Description:  根据性别获取满足条件的元素个数以及汇总数据
     * @Param: [sex]
     * @Return: void
     * @Author: abner chow
     * @Date: 2021/6/24 18:06
     */
    public static void getSumAgeBySex(String sex) {
        System.out.println("-------------------------- stream mapToInt  reduce  用法 ---------------------------------------");
        List<Person> personList = Data.getData();
        //统计满足条件的数量
        long i = personList.stream().filter(person -> person.getSex().equals(sex)).count();
        System.out.println("性别满足条件的数量：" + i);
        //mapToInt 返回一个IntStream
        int sum = personList.stream().filter(person -> person.getSex().equals(sex)).mapToInt(person -> person.getAge()).reduce((total, item) -> {
            //total 每次方法执行的返回值 ，item 每次循环的元素
            return total = total + item;
        }).getAsInt();
        System.out.println("满足条件的人的岁数总和：" + sum);

    }


    /**
     * @description 获取平均年龄
     * @param
     * @return java.lang.Double
     * @author abner chow
     * @date 2019/6/5 11:38
     */
    public static Double getAvgAge(){
        System.out.println("-------------------------- stream reduce 统计 ---------------------------------------");
        List<Person> personList = Data.getData();
        //使用map获取所有的年龄集合
        List<Integer> age = personList.stream().map((Person::getAge)).collect(Collectors.toList());
        //使用reduce汇总所有的年龄综合
        Integer sum =  age.stream().reduce(0,(count,item)->{
            //count 汇总 ，item中的每个元素
            return count + item;
        });
        return new Double(sum)/new Double(age.size());
    }


    /**
     * @description 获取所有用户的名称列表（不重复）
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2019/7/5 16:05
     */
    public static void toSetTest(){
        System.out.println("-------------------------- collect  toSet() 统计 ---------------------------------------");
        List<Person> personList = Data.getData();
        Set<String> name = personList.stream().map(Person::getName).collect(Collectors.toSet());
        System.out.println(name);
    }



    /**
     * @description 取对象中固定的属性作为map的key，value并返回map结构
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2019/9/27 16:50
     */
    public static void toMapTest(){
        System.out.println("-------------------------- collect  toMap() 统计 ---------------------------------------");
        List<Person> personList = Data.getData();
        Map<String , Integer> result = personList.stream().collect(Collectors.toMap(per-> per.getName() , v -> v.getAge()));
        result.forEach((k,v)->{
            System.out.println("k" + k  + "v" + v);

        });
    }

    /**
     * @description Collectors.toCollection() 转成新类型
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2019/7/8 11:01
     */
    public static void toTreeSet(){
        System.out.println("-------------------------- collect  toCollection() 转成新类型 TreeSet ---------------------------------------");
        List<Person> personList = Data.getData();
        TreeSet<Person> result = personList.stream().collect(Collectors.toCollection(TreeSet::new));
        System.out.println(result);
    }

    /**
     * @description 利用groupingBy() 方法按类别进行分组，实用
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2019/7/8 10:58
     */
    public static void toGroupTest(){
        System.out.println("-------------------------- collect  groupingBy() 分组 ---------------------------------------");
        List<Person> personList = Data.getData();
        Map<Boolean, List<Person> > result = personList.stream().collect(Collectors.groupingBy(person -> person.getSex().equals("man")));
        System.out.println(result);
    }


    /**
     * @description 统计各名字的数量
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2019/9/27 16:08
     */
    public static void statisticsByName(){
        System.out.println("-------------------------- collect  statisticsByName() 分组统计姓名个数 ---------------------------------------");
        List<Person> personList = Data.getData();
        Map<String , Integer>  statistics = personList.stream().map(Person::getName).filter(e -> e.equals(e)).collect(Collectors.groupingBy(f -> f, Collectors.summingInt(f -> 1)));
        System.out.println(statistics.toString());
        // 另一种实现方式
        System.out.println("------------------------- 另一种实现方式 ---------------------------------------");
        Map map = personList.stream().collect( Collectors.groupingBy(person->person.getName() , Collectors.counting()));
        System.out.println(map.toString());

    }


    /**
     * @description
     * @Param: []
     * @Return: java.util.List
     * @Author: abner chow
     * @Date: 2019/9/30 10:39
     */
    public static List getRepeatName(){
        System.out.println("-------------------------- collect  getRepeatName() 获取重复的名字 ---------------------------------------");
        List<Person> personList = Data.getData();
        List result = new ArrayList();
        result = personList.stream().collect(Collectors.groupingBy(person -> person.getName() , Collectors.counting())).entrySet().stream().filter(e -> e.getValue() > 1).map(e -> e.getKey()).collect(Collectors.toList());
        System.out.println(result.toString());
        return result;
    }


    /**
     * @description joining() 分隔
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2019/7/8 11:18
     */
    public static void toJoiningTest(){
        System.out.println("-------------------------- collect  joining() 分隔 ---------------------------------------");
        List<Person> personList = Data.getData();
        String result =  personList.stream().map(Person::getName).collect(Collectors.joining("," , "{","}"));
        System.out.println(result);
    }


    /**
     * @Description:  sort 排序
     * @Param: []
     * @Return: void
     * @Author: abner chow
     * @Date: 2021/2/5 17:53
     */
    public static void getSortList(){
        System.out.println("-------------------------- collect  sorted() 排序 ---------------------------------------");
        List<Person> personList = Data.getData();
        System.out.println("按年龄原顺序");
        personList.forEach( person -> {
            System.out.println( person.getName() + person.getAge() );
        });

        List<Person> sortList = personList.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());
        // 按年龄降序排序
        //  List<Person> reverse = personList.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());
        System.out.println("按年龄升序排序后的顺序");
        sortList.forEach( s ->{
            System.out.println( s.getName() + s.getAge() );
        } );
    }


    public static void getSortMap() {
        System.out.println("-------------------------- Map  sorted() 排序 ---------------------------------------");
        List<Person> personList = Data.getData();
        Map<Integer, Integer> map = personList.stream().collect(Collectors.toMap(Person::getIdNumber, Person::getAge));
        //获取编号、年龄组成的map用于排序
        System.out.println("原顺序");
        map.forEach((k, v) -> {
            System.out.println("idNumber:" + k + " age:" + v);
        });
        map = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(k -> k.getKey() , v -> v.getValue() , (k,v) -> k , LinkedHashMap::new ));
        System.out.println("按键值（编号）排序后");
        map.forEach((k, v) -> {
            System.out.println("idNumber:" + k + " age:" + v);
        });

    }

}
